/**
 * @file fml_log.c
 * @brief  串口日志模块
 * @author Dream Shao (1090820065@qq.com)
 * @version 1.0
 * @date 2025-07-19
 * 
 * @copyright Copyright (c) 2025
 * 
 * @par 修改日志:
 * Date       Version    Author       Description
 * 2025-07-19     1.0    Dream Shao   实现串口日志模块
 */
#include <string.h>
#include "gd32f4xx_gpio.h"
#include "gd32f4xx_usart.h"

#include "fml_log.h"
#include "logging_stack.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define LOG_TX_BUFFER_SIZE (128u)
#define LOG_RX_BUFFER_SIZE (128u)
/*******************************************************************************
 * Variables
 ******************************************************************************/
static uint8_t Log_TxBuffer[LOG_TX_BUFFER_SIZE];
static uint8_t Log_RxBuffer[LOG_RX_BUFFER_SIZE];
HDL_USART_CFG Log_UART_Cfg = {
    .tx_cfg = {
        .gpio_periph  = GPIOA,
        .alt_func_num = GPIO_AF_7,
        .pin          = GPIO_PIN_9,
     },
    .rx_cfg = {
        .gpio_periph  = GPIOA,
        .alt_func_num = GPIO_AF_7,  
        .pin          = GPIO_PIN_10,
     },
    .usart_periph = USART0,
    .baudval = 115200u,
    .msbf    = USART_MSBF_LSB, 
    .tx_irq_type = DMA1_Channel7_IRQn,
    .tx_irq_priority = 4,
    .rx_irq_type = USART0_IRQn,
    .rx_irq_priority = 5,

    .tx_dma_periph = DMA1,
    .tx_channelx   = DMA_CH7,
    .tx_sub_periph = DMA_SUBPERI4,
    .txbuffer      = Log_TxBuffer,
    .txbuf_len     = LOG_TX_BUFFER_SIZE,

    .rx_dma_periph = DMA1,
    .rx_channelx   = DMA_CH2,
    .rx_sub_periph = DMA_SUBPERI4,
    .rxbuffer      = Log_RxBuffer,
    .rxbuf_len     = LOG_RX_BUFFER_SIZE,

    .TxSem = NULL,
    .RxSem = NULL,
    .TxMutex = NULL,
};
 /******************************************************************************
 * Code
 ******************************************************************************/
/**
 * @brief  DMA发送完成终端服务函数
 * @param  无
 * @return 无
 */
 void DMA1_Channel7_IRQHandler(void)
{
    BaseType_t xResult = pdFAIL;
	BaseType_t xHigherPriorityTaskWoken = pdFAIL;
  
	if (SET == dma_interrupt_flag_get(Log_UART_Cfg.tx_dma_periph, Log_UART_Cfg.tx_channelx,DMA_INT_FLAG_FTF))
	{
		dma_interrupt_flag_clear(Log_UART_Cfg.tx_dma_periph, Log_UART_Cfg.tx_channelx,DMA_INT_FLAG_FTF);//清除中断标志位
		xResult = xSemaphoreGiveFromISR(Log_UART_Cfg.TxSem, &xHigherPriorityTaskWoken);
    }
    if (xResult != pdFAIL){
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
}
/**
 * @brief  USART接收完成中断服务函数
 */
void USART0_IRQHandler(void)
{
    BaseType_t xResult = pdFAIL;
    BaseType_t xHigherPriorityTaskWoken = pdFAIL;
    uint32_t size_test = 0;
    
    if (SET == usart_interrupt_flag_get(Log_UART_Cfg.usart_periph, USART_INT_FLAG_IDLE))
    {
        USART_STAT0(Log_UART_Cfg.usart_periph);
        USART_DATA(Log_UART_Cfg.usart_periph);
        dma_channel_disable(Log_UART_Cfg.rx_dma_periph, Log_UART_Cfg.rx_channelx);
        usart_dma_receive_config(Log_UART_Cfg.usart_periph, USART_RECEIVE_DMA_DISABLE);
        
        size_test = LOG_RX_BUFFER_SIZE - dma_transfer_number_get(Log_UART_Cfg.rx_dma_periph, Log_UART_Cfg.rx_channelx);
        LogDebug("size_test = %d\r\n",size_test);
        LogDebug("%s\r\n",Log_UART_Cfg.rxbuffer);
         /*DMA接收重启*/
        
        dma_memory_address_config(Log_UART_Cfg.rx_dma_periph, Log_UART_Cfg.rx_channelx, DMA_MEMORY_0, (uint32_t)(Log_UART_Cfg.rxbuffer));
        dma_transfer_number_config(Log_UART_Cfg.rx_dma_periph, Log_UART_Cfg.rx_channelx,LOG_RX_BUFFER_SIZE);

        dma_flag_clear(Log_UART_Cfg.rx_dma_periph, Log_UART_Cfg.rx_channelx, DMA_FLAG_FTF);
        dma_channel_enable(Log_UART_Cfg.rx_dma_periph, Log_UART_Cfg.rx_channelx);
        usart_dma_receive_config(Log_UART_Cfg.usart_periph, USART_RECEIVE_DMA_ENABLE);

        memset(Log_UART_Cfg.rxbuffer,0,LOG_RX_BUFFER_SIZE);

        xResult = xSemaphoreGiveFromISR(Log_UART_Cfg.RxSem, &xHigherPriorityTaskWoken);
    }
    if (SET == usart_interrupt_flag_get(Log_UART_Cfg.usart_periph, USART_INT_FLAG_RBNE))
    {
        usart_interrupt_flag_clear(Log_UART_Cfg.usart_periph, USART_INT_FLAG_RBNE);
        uint8_t data = usart_data_receive(Log_UART_Cfg.usart_periph);
        LogDebug("data = %c\r\n",data);
    }
    if (xResult != pdFAIL){
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
}
 /**
 * @brief  初始化串口日志模块
 * @param  无
 * @return 无
 */
void vFml_Log_Init(void)
{
    BaseType_t sta = pdPASS;

    sta = vHdl_UartInit(&Log_UART_Cfg);
    if(sta == pdFAIL)
    {
        LogError("Log UART Init Fail\r\n");
    }
}
/**
 * @brief  打印日志
 * @param  str:日志内容
 * @return 无
 */
void vFml_Log_Print(char* str)
{
    uint32_t len = strlen(str);
    // vHdl_Uart_PollingWrite(&Log_UART_Cfg, (uint8_t*)str, len);
    vHdl_Uart_DMAWrite(&Log_UART_Cfg, (uint8_t*)str, len);
}
